#ifndef SQUARECONTAINER_H
#define SQUARECONTAINER_H

/*!
 * \file     squarecontainer.h
 * \brief    Abstract mother class for Object which contains Square.
 * \author   Duriez Franck
 * \author   Carton Paul-Henri
 * \version  0.1
 */

#include "tetrisexception.h"
#include "container.h"
#include "drawable.h"
#include "qsfmlwidget.h"
#include "square.h"

class Square;

/*!
 * \class SquareContainer
 * \brief Abstract mother class for Object which contains Square.
 */
class SquareContainer : public Drawable, public Container<Square, Vector2i> /*{{{*/
{
	Q_OBJECT
	friend class Square;
/*{{{*/
public:
	/*!
	 * \brief Constructor.
	 * \param displayWidget : displayer
	 * \param parent        : parent of the widget
	 * \param dt            : pointer to the infinitesimal part of time
	 * \param size          : maximal number of Square in the container
	 */
	SquareContainer(QSFMLWidget* displayWidget, QObject* parent, float* dt, Vector2i size);

	/*!
	 * \brief Destructor.
	 */
	virtual ~SquareContainer();

private slots:
	/*!
	 * \brief   Declare that Object at coord is dead.
	 * \param   coord : coordinate of the dead Object
	 * \warning Only Square should call and only in it destructor.
	 */
	virtual void declareDeadObject(Vector2i coord) = 0;

protected:
	/*!
	 * \brief Give the square at coord the good format.
	 * \param coord : coordinate of the Object to format
	 */
	virtual void format(Vector2i coord) const throw(TetrisException::ExpectedSquare) = 0;

	Vector2i m_size;     ///< Contains width and height of the SquareContainer
	Vector2f m_center;   ///< Center of the SquareContainer
	Vector2f m_position; ///< Position of the SquareContainer
	float m_angle;       ///< Rotation of the SquareContainer
/*}}}*/

	/*************
	 * CONTAINER *
	 *************/
/*{{{*/
public:
	Square* getObject(Vector2i coord) const throw();
	/*!
	 * \warning Don't use this function to perfom internal movement,
	 * use rather SquareContainer::swap
	 */
	void setObject(Vector2i coord, Square* asquare) throw(TetrisException::UnexpectedSquare);
	void swap(Vector2i coord1, Vector2i coord2) throw();
	bool isValidCoord(Vector2i coord) const throw();
/*}}}*/

	/************
	 * DRAWABLE *
	 ************/
/*{{{*/
public:
	void setCenter(Vector2f center);
	void setPosition(Vector2f position);
	void setRotation(float angle);

	void moveCenter(Vector2f dcenter);
	void move(Vector2f dposition);
	void rotate(float dangle);

	Vector2f getCenter() const;
	Vector2f getPosition() const;
	float getRotation() const;
/*}}}*/
}; /*}}}*/

#endif // SQUARECONTAINER_H
